import javax.microedition.lcdui.Graphics;


/**
 * This is an abstract base class. Other NPC clases extends that base class. It contains common variables and methods 
 * that will be used in the NPC clases extends this class.
 */
public abstract class Monster {
    /** Patrolling state */
    public static final byte STATE_PATROLING  = 0;
   
    /** Idle state */
    public static final byte STATE_IDLE       = 1;
   
    /** Attacking state */
    public static final byte STATE_ATTACKING  = 2;
   
    /** Evading state */
    public static final byte STATE_EVADING    = 3;
   
    /** Droping state */
    public static final byte STATE_DROPING    = 4;
   
    /** Dead state */
    public static final byte STATE_DEAD       = 5;
   
    /** Dead state */
    public static final byte STATE_SEARCHING  = 6;
   
    /** Moving on the left mode */
    public static final byte MODE_MOVE_LEFT   = 0;
   
    /** Moving on the right mode */
    public static final byte MODE_MOVE_RIGHT  = 1;
   
    /** Turning on the left mode */
    public static final byte MODE_TURN_LEFT   = 2;
   
    /** Turning on the right mode */
    public static final byte MODE_TURN_RIGHT  = 3;
   
    /** Idle on the left mode */
    public static final byte MODE_IDLE_LEFT   = 4;
   
    /** Idle on the right mode */
    public static final byte MODE_IDLE_RIGHT  = 5;

    /** Death mode */
    public static final byte MODE_DEATH       = 6;

    /**
     * It's true if monster is not in STATE_DEAD state and false otherwise
     */
    public boolean isActive;
   
    /**
     * Current position x of monsters
     */
    public short posX;
   
    /**
     * Current position y of monsters
     */
    public short posY;
   
    /**
     * List of animation that will be used in the level
     * @see Animation
     */
    public Animation[] animations;
   
    /** 
     * Current state 
     */
    public byte mode;
   
    /** 
     * Current state 
     */
    public byte currentState;
   
    /** 
     * Previous state 
     */
    public byte prevState;
   
    /**
     * Current anumation
     * @see Animation
     */
    public Animation currentAnimation;

    /**
     * Constructs a Monster in the certain position with coordinates (x, y)
     * @param x horizonlat coordinate of monster
     * @param y vertical coordinate of monster
     */
    public Monster(short x, short y) {
        posX = x;
        posY = y;
        isActive = true;
    }

    /**
     * This is abstract method updates for calling update method in the class extends this class. 
     * The method update of each type of monster contains it's own stuff
     */
    public abstract void update();

    /**
     * Checks if monster intersects with marv
     */
    public abstract void checkIntersect();

    /**
     * Checks if rectangle A(aLeft, aTop, aRight, aBottom) intersects rectangle B(bLeft, bTop, bRight, bBottom)
     * @param aLeft the x coordinate of the left-top corner of rectagle A
     * @param aTop the y coordinate of the left-top corner of rectagle A
     * @param aRight the x coordinate of the right-bottom corner of rectagle A
     * @param aBottom y coordinate of the right-bottom corner of rectagle A
     * @param bLeft the x coordinate of the left-top corner of rectagle B
     * @param bTop the y coordinate of the left-top corner of rectagle B
     * @param bRight x coordinate of the right-bottom corner of rectagle B
     * @param bBottom y coordinate of the right-bottom corner of rectagle B
     * @return true is rectagles are intersected and false otherwise
     */
    public boolean isIntersect(int aLeft, int aTop, int aRight, int aBottom, int bLeft, int bTop, int bRight, int bBottom) {
        return aLeft < bRight && aRight > bLeft && aTop < bBottom && aBottom > bTop;
    }

    /**
     * Method draws the current animation of monster specified in the variable currentAnimation.
     * @param g the Graphics object to be used for rendering the Canvas
     * @param screenPosX x coordinate of left-top corner of the game screen
     * @param screenPosY y coordinate of left-top corner of the game screen
     * @exception NullPointerException if currentAnimation is null
     */
    public void draw(Graphics g, int screenPosX, int screenPosY) {
        if (isActive && isIntersect(screenPosX, screenPosY, screenPosX + MTMCanvas.width, screenPosY + MTMCanvas.height, posX - (currentAnimation.GetCurFrmHeight() >> 1), posY - currentAnimation.GetCurFrmHeight(), posX + (currentAnimation.GetCurFrmHeight() >> 1), posY)) {
            currentAnimation.Draw(g, posX - screenPosX, posY - screenPosY);
        }
    }

    /**
     * Sets new state without doing any extra work
     * @param newState the new state which should be set
     */
    public void setState(byte newState) {
        currentState = newState;
    }
   
    /**
     * Change current state to new one with with doing some work on exit old state and on enter new one
     * @param newState the new state which should be set
     */
    public void changeState(byte newState) {
        prevState = currentState;
        onExitState(currentState);
        currentState = newState;
        onEnterState(currentState);
    }
   
    /**
     * Abstarct method which should be defined in the heritable class and doing work on exit aol state
     * @param prevState the previous State
     */
    public abstract void onExitState(byte prevState);
   
    /**
     * Abstarct method which should be defined in the heritable class and doing work on exit aol state
     * @param newState the new State
     */
    public abstract void onEnterState(byte newState);
}
